<template>
	<div :class="[props.dialogLayout ? ns.b(' dialog-content') : ns.b('content')]" ref="pageDetailRef">
		<div v-for="(e, i) in renderList" :key="i" class="detail-layout-item">
			<div>
				<template v-if="e.title">
					<div class="detail-layout-item__title">{{ e.title }}</div>
					<div class="detail-layout-item__line"></div>
				</template>
				<component v-for="v in e.val" :is="v.getVNode()"></component>
			</div>
		</div>

		<!-- <div ref="workRef"></div> -->
	</div>
</template>

<script lang="ts" setup>
import { Ref, onBeforeUnmount, onMounted, ref, watch } from "vue";
import { useNamespace } from "@/hooks";
import { BasicFormBox } from "../basic-form-box";
import { BasicTaleBox } from "../basic-table-box";
import { LayoutOption } from "./types";

type BaseType = BasicFormBox<Record<string, any>> | BasicTaleBox<any>;

type RenderListType = {
	name: string;
	sort: number;
	val: BaseType[];
	title: string;
};

const props = defineProps<{
	forms: Record<string, BasicFormBox>;
	tables: Record<string, BasicTaleBox<any>>;
	layoutList: LayoutOption[];
	/** 存在则表示在弹窗中渲染 */
	dialogLayout: boolean;
}>();

const ns = useNamespace("detail-layout");
const pageDetailRef: Ref<HTMLDivElement | null> = ref(null);
const renderList = ref<RenderListType[]>([]);

/** 查询组件信息 */
const find = (name: string) => {
	const fk = Object.keys(props.forms).find(fn => fn === name);
	if (fk) {
		return { type: "form", val: props.forms[fk] } as const;
	}
	const tk = Object.keys(props.tables).find(tn => tn === name);
	if (tk) {
		return { type: "table", val: props.tables[tk] } as const;
	}
	return { type: "", val: null } as const;
};

const layoutParser = () => {
	let layoutList = props.layoutList;
	const { values, names } = blockParser(layoutList);
	// 存在 block 字段的数据全部需要被筛除
	layoutList = layoutList.filter(item => !names.includes(item.name));
	return sortParser(layoutList, values);
};

/** 解析区块信息 */
const blockParser = (layoutList: LayoutOption[]) => {
	const map: Map<string, RenderListType> = new Map();
	const names: string[] = [];
	for (let lay of layoutList) {
		if (!lay.block) continue;
		const tar = map.get(lay.block);
		const val = find(lay.name).val;
		names.push(lay.name);
		if (tar) {
			val && tar.val.push(val);
			if (tar.sort > lay.sort!) {
				tar.sort = lay.sort!;
				tar.title = lay.title!;
			}
		} else {
			// 统一处理为渲染格式
			val &&
				map.set(lay.block, {
					name: lay.name,
					sort: lay.sort!,
					val: [val],
					title: lay.title!,
				});
		}
	}
	return {
		values: [...map.values()],
		names,
	};
};

/** 解析排序信息 */
const sortParser = (layoutList: LayoutOption[], blockList: RenderListType[]): RenderListType[] => {
	// 将不存在 block 信息的配置 转换成可渲染格式
	const values = layoutList.map(item => {
		const tar = find(item.name);
		if (!tar.val) throw new Error(`${item.name} 没有被注册！！！`);
		return {
			name: item.name,
			sort: item.sort!,
			val: [tar.val],
			title: item.title || "",
		} as RenderListType;
	});

	return [...values, ...blockList].sort((a, b) => a.sort! - b.sort);
};

watch(
	() => props,
	() => {
		renderList.value = renderList.value.slice();
	},
	{ deep: true }
);

onMounted(() => {
	renderList.value = layoutParser();
});
</script>

<style lang="scss" scoped>
$ns: detail-layout;

@include block(#{$ns}-content) {
	width: 100%;
	display: flex;
	flex-direction: column;
	padding: 20px;
	box-sizing: border-box;

	:deep(.detail-layout-item) {
		margin-bottom: 20px;
		padding: 20px;
		border-radius: 6px;
		box-shadow: 1px 1px 15px 3px #dfdfdf;
		background-color: var(--bg-color-light1);

		.detail-layout-item__title {
			color: black;
			font-size: 22px;
			font-weight: 700;
			margin-bottom: 5px;
		}

		.detail-layout-item__line {
			height: 1px;
			width: 100%;
			background-color: #ccc;
			margin-bottom: 15px;
		}
	}
}

@include block(#{$ns}-dialog-content) {
	width: 100%;
	display: flex;
	flex-direction: column;
	box-sizing: border-box;

	:deep(.detail-layout-item) {
		margin-bottom: 20px;
		border-radius: 6px;
		// box-shadow: 1px 1px 15px 3px #dfdfdf;
		background-color: var(--bg-color-light1);

		.detail-layout-item__title {
			color: black;
			font-size: 22px;
			font-weight: 700;
			margin-bottom: 5px;
		}

		.detail-layout-item__line {
			height: 1px;
			width: 100%;
			background-color: #ccc;
			margin-bottom: 15px;
		}
	}
}
</style>
